
#ifndef ULEB128_H
#define ULEB128_H

typedef struct {
    ubyte val <comment="uleb128 element">;
    if(val > 0x7f) {
        ubyte val <comment="uleb128 element">;
        if (val > 0x7f) {
            ubyte val <comment="uleb128 element">;
            if(val > 0x7f) {
                ubyte val <comment="uleb128 element">;
                if(val > 0x7f) {
                    ubyte val <comment="uleb128 element">;
                }
            }
        }
    }
} uleb128 <read=ULeb128Read, comment="Unsigned little-endian base 128 value">;

// get the actual uint value of the uleb128
uint uleb128_value(uleb128 &u) {
    local uint result;
    local ubyte cur;

    result = u.val[0];
    if(result > 0x7f) {
        cur = u.val[1];
        result = (result & 0x7f) | (uint)((cur & 0x7f) << 7);
        if(cur > 0x7f) {
            cur = u.val[2];
            result |= (uint)(cur & 0x7f) << 14;
            if(cur > 0x7f) {
                cur = u.val[3];
                result |= (uint)(cur & 0x7f) << 21;
                if(cur > 0x7f) {
                    cur = u.val[4];
                    result |= (uint)cur << 28;
                }
            }
        }
    }

    return result;
}

string ULeb128Read(uleb128 &u) {
    local string s;
    local uint v = uleb128_value(u);
    s = SPrintf(s, "%ld (0x%X)", v, v);
    return s;
}

#endif